feat: add compat.godot-cpp 4.5.0 - #143
Merged
Merged
Conversation
godot-cpp's tag archives are only half a source tree: the ~1000 GDExtension engine classes and every builtin Variant type (gen/include, gen/src) are emitted by upstream's own binding_generator.py at build time, and ship in no upstream archive or release. Running that generator on the consumer side would make Python a hard dependency of every build on every platform, so it runs once offline instead and the result is published as an immutable mirror archive: upstream's tree byte-for-byte plus gen/. tools/godot-cpp/repack.sh is the only source of that archive and verifies it -- it diffs the regenerated tree against a fresh extraction of the upstream archive and refuses to publish if any upstream file differs, then packs deterministically (sorted, fixed mtime, gzip -n). Two runs hash identically. GLOBAL github.com/xlings-res/godot-cpp 4.5.0 CN gitcode.com/mcpp-res/godot-cpp 4.5.0 sha256 b0c36e77f02c4181352cdd7547b209b93a833be1ad6197f8c650d92987221a00 GDEXTENSION is upstream's PUBLIC compile definition, so it rides on a default feature and reaches consumer TUs. DEBUG_ENABLED / DEV_ENABLED / HOT_RELOAD_ENABLED are deliberately not features (each re-keys the store into a second full 1022-TU build, and HOT_RELOAD_ENABLED changes the Wrapped layout); REAL_T_IS_DOUBLE cannot be one at all, since it needs a gen/ tree generated with precision=double. The test member asserts on both halves and can fail on either: Vector2:: length(), Basis::orthonormalized(), Color::to_rgba32() and AABB::get_volume() are defined in src/variant/*.cpp, so they only resolve if the library really compiled and linked, while Node, Node::PROCESS_MODE_*, godot::OK and Variant::OBJECT exist only in gen/. Everything a running Godot process would be needed for (String, Array, class registration) is out of scope. Verified locally with the CI-pinned mcpp 2026.8.3.3: `mcpp test -p godot-cpp` -> test result ok. 1 passed; 0 failed (106.54s).
A GDExtension is a shared library, so compat.godot-cpp's objects are
almost always linked into one -- and without position-independent code
that link fails outright:
ld: obj/vector4i.o: relocation R_X86_64_32 against `.rodata` can not
be used when making a shared object; recompile with -fPIC
which leaves the package unable to do the one thing it exists for.
Upstream's own SCons and CMake builds pass -fPIC for the same reason.
Windows does not need it: the PE toolchain has no such distinction and
clang-cl would only report the flag as unused.
Caught by building a real GDExtension (kind = "shared") against the
package, not by inspection. With it, that shared library links and
exports its entry symbol, and the workspace member still passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
compat.godot-cpp4.5.0 (upstream taggodot-4.5-stable) — the C++ bindings for Godot's GDExtension API, consumable as an ordinary mcpp source package:#include <godot_cpp/...>, no SCons, no CMake, no Python.Shape: upstream codegen frozen into the mirror archive
godot-cpp's tag archives are half a source tree. The other half — ~1000 engine classes and every builtin Variant type, i.e.
gen/include/andgen/src/— is emitted by upstream's ownbinding_generator.pyfromgdextension/extension_api.jsonat build time, and ships in no upstream archive or release:Three ways to get it, and why this one:
install()hook runs python on the consumer sidegen/)gen/throughgenerated_filesSo the download is a repack, in the same spirit as the asio symlink repack: upstream's tree byte-for-byte, plus
gen/.tools/godot-cpp/repack.shis the archive's only source and its verifier — it re-extracts the upstream archive,diff -rs it against the generated tree and refuses to publish if any upstream file differs, then packs deterministically (--sort=name, fixed mtime,gzip -n). Two independent runs hash identically.Mirrors
github.com/xlings-res/godot-cpp/releases/download/4.5.0/godot-cpp-4.5.0.tar.gzgitcode.com/mcpp-res/godot-cpp/releases/download/4.5.0/godot-cpp-4.5.0.tar.gzBoth re-downloaded and hashed:
b0c36e77f02c4181352cdd7547b209b93a833be1ad6197f8c650d92987221a00, identical to the local build. Upstreamgodot-4.5-stablearchive isac78539c0042554c494ea419549d2de88758d448721aeb0e5d41129aa87e339c; both are recorded in the mirror repo's README together with the reproduction recipe.One OS-neutral archive for all three platforms — godot-cpp is portable C++ with no per-platform source selection; the platform split lives in Godot itself, behind the
gdextension_interface.hC ABI.Defines / features
GDEXTENSIONis upstream's PUBLIC compile definition (cmake puts it on the target's INTERFACE), so library and consumer TUs must agree — it rides ondefault = { implies = { "gdextension" } }, the same shape asCURL_STATICLIBincompat.curl.Deliberately not features:
DEBUG_ENABLED/DEV_ENABLED— extra checks, off in upstream's release default.HOT_RELOAD_ENABLED— changes theWrappedlayout; that is ABI, not a switch.REAL_T_IS_DOUBLE— needs agen/tree generated withprecision=double, which is not in this archive. It could only ever be a separate version/package, never a feature over these bytes.Shared reason for the first two: each re-keys the store into a second full 1022-TU build of the same library.
Test member
tests/examples/godot-cpp/(inherits the workspace-rootcompatredirect). Both halves are asserted, and either can fail:Vector2::length(),Basis::orthonormalized(),Color::to_rgba32(),AABB::get_volume()are declared in headers but defined insrc/variant/*.cpp, so a pass proves the 1022 TUs really compiled and linked in.<godot_cpp/classes/node.hpp>,Node::PROCESS_MODE_*,godot::OK,godot::ERR_FILE_NOT_FOUND,Variant::OBJECTexist only undergen/.Out of scope by nature: anything routed through the
gdextension_interface_*function pointers (String,Array, class registration) needs a Godot process that has loaded the extension. The pure-math half does not, so that is where the assertions live.Verification
Cold run with the CI-pinned mcpp (
MCPP_VERSION = 2026.8.3.3):Local lint mirrors
validate.yml(syntax, required fields, no leadingv, mirror table, package name, cross-package refs,mcpp xpkg parse) — all clean, and the CN url returns 200.Separately, all 1022 TUs were built once with gcc 13 at
-std=c++23and every object linked eagerly against the test'smainto confirm no unresolved symbols under whole-object dependency linking (no-ldl/-lpthreadneeded). ~16 CPU-minutes, so ~4–5 min on a 4-core runner.Note
src/core/object.cppandgen/src/classes/object.cppshare a basename — covered by mcpp's obj-path disambiguation (mcpp#233/#240), well below this index's client floor, and verified by the passing link.Follow-up (separate PR)
The C++23 module layer stays out of this index: it will be the external Form-A package
mcpplibs/godot-cpp-m, depending oncompat.godot-cppand exposingimport godot_cpp;, registered here aspkgs/g/godotengine.godot-cpp.lua.That has to come after this one merges and
publish-artifactrepublishes: a module test member can declare only one[indices]redirect (godotengine), so its transitivecompat.godot-cppresolves from the published index — the same constrainttests/examples/ffmpeg-moduledocuments.Design notes:
.agents/docs/2026-08-04-add-godot-cpp-plan.md.